package com.huang.security.extension.refresh;

import com.huang.constant.Common;
import com.huang.enums.AuthenticationMethodEnum;
import com.huang.security.service.CustomUserDetailsService;
import com.huang.util.RequestUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.util.Assert;

import java.util.Map;

/**
 * @author han
 * @since 2022-02-14 15:05:22
 */
public class PreAuthenticatedUserDetailsService<T extends Authentication> implements AuthenticationUserDetailsService<T>, InitializingBean {

    private final Map<String, UserDetailsService> userDetailsServiceMap;

    public PreAuthenticatedUserDetailsService(Map<String, UserDetailsService> userDetailsServiceMap) {
        Assert.notNull(userDetailsServiceMap, "userDetailsService cannot be null.");
        this.userDetailsServiceMap = userDetailsServiceMap;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(this.userDetailsServiceMap, "UserDetailsService must be set");
    }

    /**
     * 重写PreAuthenticatedAuthenticationProvider 的 preAuthenticatedUserDetailsService 属性，
     * 可根据客户端和认证方式选择用户服务 UserDetailService 获取用户信息 UserDetail
     *
     */
    @Override
    public UserDetails loadUserDetails(T authentication) throws UsernameNotFoundException {
        String clientId = RequestUtils.getOAuth2ClientId();
        AuthenticationMethodEnum methodEnum = AuthenticationMethodEnum.getByValue(RequestUtils.getAuthenticationMethod());

        UserDetailsService userDetailsService = userDetailsServiceMap.get(clientId);


        if (Common.Client.ADMIN_CLIENT_ID.equals(clientId)) {
            CustomUserDetailsService customUserDetailsService = (CustomUserDetailsService) userDetailsService;
            if (methodEnum == AuthenticationMethodEnum.MOBILE) {
                return customUserDetailsService.loadUserByMobile(authentication.getName());
            }
            return customUserDetailsService.loadUserByUsername(authentication.getName());

        }

        if (Common.Client.APP_ANDROID_CLIENT_ID.equals(clientId)) {
            CustomUserDetailsService customUserDetailsService = (CustomUserDetailsService) userDetailsService;
            if (methodEnum == AuthenticationMethodEnum.MOBILE) {
                return customUserDetailsService.loadUserByMobile(authentication.getName());
            }
            return customUserDetailsService.loadUserByUsername(authentication.getName());
        }

        return null;
    }
}
